﻿namespace Sitecore.ChangesTracker.Commands
{
    using System;
    using System.Collections.Specialized;
    using System.Linq;
    using Sitecore;
    using Data.Archiving;
    using Diagnostics;
    using Globalization;
    using Text;
    using Web.UI.Sheer;
    using Web.UI.WebControls;
    using Web.UI.XamlSharp.Continuations;
    using Sitecore.Web;
    using Sitecore.ChangesTracker.Exceptions;
    using Sitecore.ChangesTracker.Archiving;
    using Sitecore.StringExtensions;

    public class Restore : Shell.Framework.Commands.Command, ISupportsContinuation
    {
        public override void Execute(Sitecore.Shell.Framework.Commands.CommandContext context)
        {
            Assert.ArgumentNotNull(context, "context");
            string str = context.Parameters["item"];

            if (string.IsNullOrEmpty(str))
            {
                SheerResponse.Alert("Select an item first.", new string[0]);
            }
            else
            {
                NameValueCollection parameters = new NameValueCollection();
                parameters["item"] = str;
                parameters["archivename"] = context.Parameters["archivename"];
                parameters["close"] = context.Parameters["close"];
                ClientPipelineArgs args = new ClientPipelineArgs(parameters);
                if (ContinuationManager.Current != null)
                {
                    ContinuationManager.Current.Start(this, "Run", args);
                }
                else
                {
                    Context.ClientPage.Start(this, "Run", args);
                }
            }
        }
        public override string GetClick(Shell.Framework.Commands.CommandContext context, string click)
        {

            string clc = base.GetClick(context, click);
            if (click.Contains("app=compare"))
            {
                int ind = clc.IndexOf(')');
                string param = "item=" + context.Parameters["arc_id"] + ",archivename=" + context.Parameters["archivename"];
                if (ind > 0)
                {
                    clc = clc.Insert(ind, "," + param);
                }
                else
                {
                    clc = "(" + param + ")";
                }
            }
            return clc;
        }

        public void Run(ClientPipelineArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if (args.IsPostBack)
            {
                if (args.Result == "yes")
                {
                    ChangeTrackerArchive.EntryState state = args.CustomData["entrystate"] as ChangeTrackerArchive.EntryState;
                    Assert.IsNotNull(state, "state cannot be null");
                    if (state.Cahnges == ChangeTrackerArchive.ChangesLevel.NoTemplate)
                    {
                        return;
                    }
                    ChangeTrackerArchive archive = ArchiveManager.Providers["changetracker"].GetArchive(args.Parameters["archivename"], Context.ContentDatabase) as ChangeTrackerArchive;
                    Assert.IsNotNull(archive, typeof(ChangeTrackerArchive));
                    if (state.Cahnges == ChangeTrackerArchive.ChangesLevel.CriticalCanges)
                    {
                        UrlString url = new UrlString(UIUtil.GetUri("control:Sitecore.ChangesTracker.UI.TemplateComparer"));
                        url.Add("arcid", state.ControlPointId.ToString());
                        url.Add("arcName", archive.Name);
                        SheerResponse.ShowModalDialog(url.ToString(), "1100", "500", string.Empty, false);
                        SheerResponse.SetLocation(string.Empty);
                        return;
                    }
                    int num = 0;
                    ListString str = new ListString(args.Parameters["item"]);
                    foreach (string str2 in str)
                    {
                        Guid archivalId = new Guid(str2);
                        try
                        {
                            archive.RestoreItem(archivalId, args.Parameters["force"] == "1");
                            Log.Audit(this, "Restore: archive: {0}, id: {1}", new string[] { archive.Name, archivalId.ToString() });
                            continue;
                        }
                        catch (TemplateChangedException e)
                        {
                            Log.Error(string.Format("Restore: failed to restore: {0}, error: {1}", str2, e.Message), this);
                            SheerResponse.Alert(Translate.Text("{0} item could not be restored because its template has been changed.", new object[] { e.ItemPath }), new string[0]);
                            continue;
                        }
                        catch (Exception exception)
                        {
                            num++;
                            Log.Error(string.Format("Restore: failed to restore: {0}, error: {1}", str2, exception.Message), this);
                            continue;
                        }

                    }

                    if (num > 0)
                    {
                        SheerResponse.Alert(Translate.Text("{0} items could not be restored because of either security permissions or errors.", new object[] { num }), new string[0]);
                    }

                    if (args.Parameters["close"] == "1")
                    {
                        SheerResponse.Eval("if(window.parent!=null&&window.parent.parent!=null&&window.parent.parent.scManager!= null){window.parent.parent.scManager.closeWindow(window.parent);}else{window.close()}");
                    }
                    else
                    {
                        SheerResponse.SetLocation(string.Empty);
                    }
                }
            }
            else
            {
                ChangeTrackerArchive archive2 = ArchiveManager.Providers["changetracker"].GetArchive(args.Parameters["archivename"], Context.ContentDatabase) as ChangeTrackerArchive;
                Assert.IsNotNull(archive2, typeof(Archive));



                ListString str3 = new ListString(args.Parameters["item"]);

                string message = "Do you want to restore selected item(s)?";
                foreach (string id in str3)
                {

                    Guid archivalId = new Guid(id);
                    ChangeTrackerArchiveEntry entry = archive2.GetSingleEntry(archivalId) as ChangeTrackerArchiveEntry;
                    if (entry == null)
                    {
                        SheerResponse.Alert("Item not found.", new string[0]);
                        return;
                    }
                    ChangeTrackerArchive.EntryState state = new ChangeTrackerArchive.EntryState(ChangeTrackerArchive.ChangesLevel.Ok, Guid.Empty);
                    if (entry.Reason == "created")
                    {
                        message = "Item \"{0}\" will be deleted. Do you want to proceed?".FormatWith(new object[] { entry.Name });
                    }
                    else
                    {
                        if (!entry.IsTemplate)
                        {
                            state = archive2.CheckTemplateConsistency(entry);
                            switch (state.Cahnges)
                            {
                                case ChangeTrackerArchive.ChangesLevel.Ok:
                                    message = "Do you want to restore selected item(s)?";
                                    break;
                                case ChangeTrackerArchive.ChangesLevel.Changed:
                                    message = "Items template has been changed. If you restore it some data may be lost. Do you want to proceed?\n\nNote: It is recommended to run database clean up after this operation.";
                                    args.Parameters["force"] = "1";
                                    break;
                                case ChangeTrackerArchive.ChangesLevel.CriticalCanges:
                                    message = "Items template contains critical chnages. Item cannot be restored. Please restore template first.\n\nDo you want to view items template?";
                                    //SheerResponse.Alert(message, new string[0]);
                                    break;
                                case ChangeTrackerArchive.ChangesLevel.NoTemplate:
                                    message = "Item tmplate was deleted sicne this audit point had been created. Restore the template first.";
                                    break;

                            }
                        }
                        else
                        {
                            message = "You are about to restore a template audit point. If you restore it some data may be lost. Do you want to proceed?\n\nNote: It is recommended to run database clean up after this operation.";
                            args.Parameters["force"] = "1";
                        }
                    }
                    //bool flag=archive2.CheckTemplateConsistency(archivalId);
                    //if (!flag)
                    //{
                    //    message = "Items template has been changed. If you restore it some data may be lost. Do you want to proceed? \n\n Note: It is recommended to run database clean up after this operation.";
                    //    args.Parameters["force"] = "1";
                    //}

                    args.CustomData.Add("entrystate", state);

                    string name = entry.Name;
                    if (state.Cahnges == ChangeTrackerArchive.ChangesLevel.NoTemplate)
                    {
                        SheerResponse.Alert(message);
                    }
                    else
                    {
                        SheerResponse.Confirm(Translate.Text(message, new object[] { name }));
                    }
                    
                }

                args.WaitForPostBack();
            }
        }
    }
}

